GO
1. Shell数组介绍
1.1. 为什么会产生Shell数组
通常在开发Shell脚本时,定义变量采用的形式为a=1;b=2;c=3
,可如果有多个变量呢?这时再逐个地定义就会很费劲,并且要是有多个不确定的变量内容,也会难以进行变量定义,此外,快速读取不同变量的值也是一件很痛苦的事情,于是数组就诞生了,它就是为了解决上述问题而出现的。
1.2. 什么是Shell数组
简单地说,Shell的数组就是一个元素集合,它把有限个元素(变量或字符内容)用一个名字来命令,然后用编号对它们进行区分。这名字就称为数组名,用于区分不同内容的编号就称为数组下标。组成数组的各个元素(变量)称为数组的元素,有时也称为下标变量。
有了Shell数组之后,就可以用相同名字来引用一系列变量及变量值了,并通过数字(索引)来识别使用它们。在很多场合中,使用数组可以缩短和简化程序开发。
2. Shell数组的定义与增删改查
2.1. Shell数组的定义
Shell数组的定义有多种方法,列举如下:
方法1
用小括号将变量值括起来赋值给数组变量,每个变量值之间要用空格进行分隔。
语法:array=(value1 value2 value3 ...)
示例如下:
方法2
用小括号将变量值括起来,同时采用键值对的形式赋值。
语法:array=([1]=one [2]=two [3]=three)
此种方法为key-value
键值对的形式,小括号里对应的数字为数组下标,等号后面的内容为下标对应的数组变量的值,此方法比较复杂,不推荐使用。
示例如下:
方法3
通过分别定义数组变量的方法来定义。
语法:array[0]=a; array[1]=b; array[2]=c
此种定义方法比较麻烦,不推荐使用。
示例如下:
方法4
动态地定义数组变量,并使用命令的输出结果作为数组的内容。
语法:
示例如下:
方法5
还可以使用declare -a array
来定义数组类型,但是这样用的情况比较少。一般不用。了解即可。
2.2. Shell数组的打印及输出
1. 打印数组元素
此为常用知识点,需要重点掌握。
- 打印单个数组元素用
${数组名[下标]}
,当未指定数组小标时,数组的小标将从0开始。 - 使用
*
或@
可以得到整个数组的内容。
示例如下:
2. 打印数组元素的个数
此为常用知识点,需要重点掌握。
- 使用
${井数组名[@或*]}
可以得到数组的长度。 - 这和变量子串的知识是一样的,因为数组也是变量,只不过是特殊的变量,因此变量的子串替换等知识也适用于数组。
示例如下:
3. 数组赋值
此知识不常用,了解即可。
- 可直接通过
数组名[下标]
对数组进行引用赋值,如果下标不存在,则自动添加一个新的数组元素,如果小标存在,则覆盖原来的值。
示例如下:
4. 数组的删除
因为数组本质上还是变量,因此可通过unset 数组[下标]
清除相应的数组元素,如果不带下标,则表示清除整个数组的所有数据。
示例如下:
5. 数组内容的截取和替换
这里和变量子串的替换是一样的,因为数组是特殊的变量。
数组元素部分的内容截取的示例如下:
替换数组元素部分内容的代码如下:
提示:调用方法为
${数组名[@或*]/查找字符/替换字符}
,该操作不会改变原先数组的内容,如果需要修改,可以参考上面的例子,重新定义数组。
删除数组元素部分内容的代码如下:
提示:数组也是变量,因此也适合于前面讲解过的变量的子串处理的功能应用。数组的其他相关知识可通过
man bash
命令然后搜索Areays
来了解。
3. Shell数组脚本开发实践
范例1:使用循环批量输出数组的元素
方法1:通过C语言型的for循环语句打印数组元素
123456array=(1 2 3 4 5)for ((i=0; i<${#array[*]}; i++))doecho ${array[i]}done方法2:通过普通for循环语句打印数组元素
123456array=(1 2 3 4 5)for n in ${array[*]}doecho $ndone方法3:使用while循环语句打印数组元素
12345678array=(1 2 3 4 5)i=0while ((i<${#array[*]}))doecho ${array[i]}((i++))done
范例2:通过竖向列举法定义数组元素并批量打印
4. Shell数组的重要命令
4.1. 定义命令
- 静态数组:
array=(1 2 3)
- 动态数组:
array=($(ls))
- 为数组赋值:
array[3]=4
4.2. 打印命令
- 打印所有元素:
${array[@]}
或${array[*]}
- 打印数组长度:
${井array[@]}
或${井array[*]}
- 打印单个元素:
${array[i]}
其中i是数组下标
4.3. 循环打印的常用基本语法
|
|
5. Shell数组相关面试题及高级实战案例
5.1. 范例1
利用bash for循环打印下面这句话中字母数不大于6的单词(某企业面试真题):I am theshu teacher welcome to theshu training class
解答思路具体如下:
- 先把所有的单词放到数组里,然后一次进行判断。命令:
array=(I am theshu teache welcome to theshu training class)
计算变量内容的长度。常见的方法有4种:
char=theshu
echo $char | wc -L
echo ${井char}
expr length $char
echo $char | awk '{print length($0)}'
方法1:通过数组方法来实现(本例给出了用两种for循环打印数组元素的方法):
123456789101112131415arr=(I am theshu teacher welcome to theshu training class)for ((i=0; i<${#arr[*]; i++}))doif [ ${#arr[$i]} -lt 6 ]thenecho "${arr[$i]}"fidoneecho ------------for word in ${array[*]}doif [ `expr length $word` -lt 6 ];thenecho $wordfidone方法2:使用for循环列举取值列表法:
123456789101112131415for word in I am theshu teacher welcome to trheshu training classdoif [ `echo $word | wc -L` -lt 6 ]; thenecho $wordfidonechars="I am theshu teacher welcome to theshu training class"for word in $charsdoif [ `echo $word | wc -L` -lt 6 ]; thenecho $wordfidone方法3:通过awk循环实现
12chars-"I am theshu teacher welcome ti theshu training class"echo $chars | awk '{for(i=1;i<NF;i++) if(length($i)<=6) print $i}'
5.2. 范例2
批量检查多个网站地址是否正常。要求如下:
- 使用Shell数组的方法实现,检测策略尽量模拟用户访问
- 每10秒进行一次全部检测,无法访问的输出报警
- 待检测的地址如下:1234http://blog.theshu1.comhttp://blog.theshu2.comhttp://blog.theshu3.comhttp://10.0.0.7
解体思路:
- 把URL定义成数组,形成函数
- 编写URL检查脚本函数,传入数组的元素,即URL
- 组合实现整个案例,编写main主函数(即执行函数),每隔10秒检查一次
下面的参考答案采用了Shell数组的方法,同时检测多个URL是否正常,并给出专业的展示效果:
提示:实际使用时,一些基础的函数脚本(例如:加颜色的函数)是放在函数文件里的(例如:放在/etc/init.d/functions里),与执行的脚本内容部分分离,这样看起来会更清爽,大型的语言程序都是这样开发的。
OK